package basic.thread.again.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**使用condition实现线程之间的通信
 * @author bingo
 * @Date 2018/3/11
 */
public class Demo2 {

    private int  single;

    private Lock lock = new ReentrantLock();

    Condition a = lock.newCondition();
    Condition b = lock.newCondition();
    Condition c = lock.newCondition();


    public synchronized void a(){
        lock.lock();
        while (single!=0){
            try {
                a.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("a");
        single++;
        b.signal();
        lock.unlock();
    }
     public synchronized void b (){
         lock.lock();
        while (single!=1){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
         System.out.println("b");
        single++;
        c.signal();
        lock.unlock();

        }
    public synchronized void c (){
      lock.lock();
        while (single!=2){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("c");
        single=0;
        a.signal();
        lock.unlock();

    }

    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        A t1 = new A(demo1);
        B t2 = new B(demo1);
        C t3 = new C(demo1);

        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();



    }

}

class A  implements Runnable{

    private Demo1 demo1;

    public A(Demo1 demo1) {
        this.demo1 = demo1;
    }

    @Override
    public void run() {

        while (true){
            demo1.a();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class B  implements Runnable{

    private Demo1 demo1;

    public B(Demo1 demo1) {
        this.demo1 = demo1;
    }

    @Override
    public void run() {

        while (true){
            demo1.b();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class C  implements Runnable{

    private Demo1 demo1;

    public C(Demo1 demo1) {
        this.demo1 = demo1;
    }

    @Override
    public void run() {

        while (true){
            demo1.c();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}